package gat.application.tg.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bitsun.core.common.exception.AppException;
import com.bitsun.core.common.exception.ErrorCode;
import com.bitsun.core.common.persistence.BasePService;
import com.bitsun.core.common.persistence.IPService;
import com.bitsun.core.common.persistence.Pager;
import com.bitsun.core.common.persistence.QueryParamUtils;
import com.google.common.base.CaseFormat;
import gat.application.tg.UserBotService;
import gat.common.util.CurrentThread;
import gat.convertor.tg.UserBotReqDtoConvertor;
import gat.convertor.tg.UserBotResDtoConvertor;
import gat.dto.req.tg.UserBotReqDto;
import gat.dto.req.tg.UserRelationBotReqDto;
import gat.dto.res.backgroundUser.RolePermissionsResDto;
import gat.dto.res.tg.TgBotResDto;
import gat.dto.res.tg.UserBotResDto;
import gat.infrastructure.persistence.dao.tg.UserBotMapper;
import gat.infrastructure.persistence.po.backgroundUser.RolePermissionsPo;
import gat.infrastructure.persistence.po.tg.TgBotPo;
import gat.infrastructure.persistence.po.tg.UserBotPo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 示例表，应用（业务编排）层实现
 * @author: yanshukeji-java
 * @email: yanshukeji-java
 */
@Slf4j
@Service("userBotAppService")
@Transactional(rollbackFor = Exception.class)
public class UserBotServiceImpl implements UserBotService {

    @Autowired
    private UserBotReqDtoConvertor userBotReqDtoConvertor;

    @Autowired
    private UserBotResDtoConvertor userBotResDtoConvertor;

    private IPService<UserBotPo> userBotPoService;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    public UserBotServiceImpl(UserBotMapper userBotMapper) {
        this.userBotPoService = new BasePService(userBotMapper);
    }



    @Override
    public UserBotResDto save(UserBotReqDto reqDto) {
        UserBotPo po = userBotReqDtoConvertor.dto2Po(reqDto);
        userBotPoService.save(po);
        UserBotResDto resDto = userBotResDtoConvertor.po2Dto(po);
        return resDto;
    }

    @Override
    public boolean deleteByIds(String ids) {
        try {
            List<Long> idLongList =
            Arrays.asList(ids.split(",")).stream().map(s -> NumberUtils.createLong(s.trim())).collect(Collectors.toList());
            return userBotPoService.removeByIds(idLongList);
        } catch (Exception e) {
            throw new AppException("参数错误：" + ids, ErrorCode.pc("417"), e);
        }
     }

    @Override
    public Pager<UserBotResDto> doPager(Map<String, Object> params) {
        Pager<UserBotPo> poPager = userBotPoService.queryPage(params, UserBotPo.class);
        Pager<UserBotResDto> resDtoPager = userBotResDtoConvertor.convertPoPager2ResDtoPager(poPager);
        return resDtoPager;
    }

    @Override
    public UserBotResDto selectOne(Long id) {
        UserBotPo po = userBotPoService.getById(id);
        UserBotResDto resDto = userBotResDtoConvertor.po2Dto(po);
        return resDto;
    }

    @Override
    public UserBotResDto selectOne(Map<String, Object> params) {
        QueryWrapper queryWrapper = QueryParamUtils.queryWrapper4eq(UserBotPo::new, params);
        queryWrapper.last(" limit 1");
        UserBotPo po = userBotPoService.getOne(queryWrapper);
        UserBotResDto resDto = userBotResDtoConvertor.po2Dto(po);
        return resDto;
    }

    @Override
    public boolean updateProps(Long id, Map<String, Object> params) {
        UpdateWrapper<UserBotPo> updateWrapper = QueryParamUtils.updateWrapper4Map(UserBotPo::new, id, params);
        return userBotPoService.update(new UserBotPo(), updateWrapper);
        }

    @Override
    public boolean updateProps(Long id, UserBotReqDto reqDto) {
        UserBotPo po = userBotReqDtoConvertor.dto2Po(reqDto);
        po.setId(id);
        return userBotPoService.updateById(po);
    }


    @Override
    public boolean updateAllProps(Long id, UserBotReqDto reqDto) {
        UpdateWrapper<UserBotPo> updateWrapper = Wrappers.update();
        updateWrapper.eq("id", id);
        Field[] fields = UserBotReqDto.class.getDeclaredFields();
        Arrays.stream(fields).filter(f -> !Modifier.isStatic(f.getModifiers())).forEach(field -> {
        try {
        PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), UserBotReqDto.class);
        Method getMethod = propertyDescriptor.getReadMethod();
        String fileNameCamel = getMethod.getName().substring(3);
        String fileNameUnderline = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, fileNameCamel);
        updateWrapper.set(fileNameUnderline, getMethod.invoke(reqDto));
        } catch (Exception ex) {
        log.warn("属性不存在get方法："+field.getName(),ex);
        }
        });
        return userBotPoService.update(new UserBotPo(), updateWrapper);
    }

    @Override
    public void saveRelationBot(UserRelationBotReqDto reqDto) {
        QueryWrapper<UserBotPo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserBotPo::getBotId,reqDto.getBotId());
        UserBotPo userBotPo = userBotPoService.getOne(queryWrapper);
        if (userBotPo != null){
            throw new AppException("该机器人已被绑定");
        }
        UserBotPo po = new UserBotPo();
        po.setUserCode(reqDto.getUserCode());
        po.setBotId(reqDto.getBotId());
        userBotPoService.save(po);
    }

    @Override
    public UserBotResDto getUserBotByUserCode(String userCode) {
        return userBotResDtoConvertor.po2Dto(userBotPoService.getOne(new LambdaQueryWrapper<UserBotPo>()
                .eq(UserBotPo::getUserCode,userCode)
        ));
    }

    @Override
    public List<UserBotPo> selectAll() {

        String username = CurrentThread.getCurrentUser().getUsername();
        if (!StringUtils.equals(username, "admin")) {
            UserBotPo userBotPo = userBotPoService.getOne(new LambdaQueryWrapper<UserBotPo>()
                    .eq(UserBotPo::getUserCode, CurrentThread.getCurrentUser().getUserCode())
            );
            if (userBotPo != null ) {
                List<UserBotPo> resDto = new ArrayList<>();
                resDto.add(userBotPo);
                return resDto;
            }
            return new ArrayList<>();
        }
        return userBotPoService.list();
    }

}